package cn.schoolwow.workflow.module.parent.kit;

import cn.schoolwow.workflow.module.common.domain.QuickWorkFlowConfig;
import cn.schoolwow.workflow.module.definition.action.kit.WorkFlowDeployActionImpl;
import cn.schoolwow.workflow.module.definition.query.kit.WorkFlowDeployQueryImpl;
import cn.schoolwow.workflow.module.instance.action.kit.WorkFlowInstanceActionServiceImpl;
import cn.schoolwow.workflow.module.instance.query.kit.WorkFlowInstanceQueryServiceImpl;
import cn.schoolwow.workflow.module.option.kit.WorkFlowOptionImpl;
import cn.schoolwow.workflow.module.task.action.kit.WorkFlowTaskActionServiceImpl;
import cn.schoolwow.workflow.module.task.query.kit.WorkFlowTaskQueryServiceImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 代理模式对象
 */
public class WorkFlowInvocationHandler implements InvocationHandler {
    private Object[] interfaceInstanceArray;

    public WorkFlowInvocationHandler(QuickWorkFlowConfig quickWorkFlowConfig) {
        interfaceInstanceArray = new Object[]{
                new WorkFlowOptionImpl(quickWorkFlowConfig),
                new WorkFlowDeployQueryImpl(quickWorkFlowConfig),
                new WorkFlowDeployActionImpl(quickWorkFlowConfig),
                new WorkFlowInstanceQueryServiceImpl(quickWorkFlowConfig),
                new WorkFlowInstanceActionServiceImpl(quickWorkFlowConfig),
                new WorkFlowTaskQueryServiceImpl(quickWorkFlowConfig),
                new WorkFlowTaskActionServiceImpl(quickWorkFlowConfig)
        };
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String interfaceName = method.getDeclaringClass().getSimpleName();
        for(Object interfaceInstance:interfaceInstanceArray){
            Class interfaceClass = interfaceInstance.getClass().getInterfaces()[0];
            if(interfaceClass.getSimpleName().equalsIgnoreCase(interfaceName)){
                try {
                    return method.invoke(interfaceInstance, args);
                }catch (InvocationTargetException e){
                    Throwable targetException = e.getTargetException();
                    throw targetException;
                }
            }
        }
        return method.invoke(this, args);
    }
}
